﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using DcsGauges.Gui.Rendering;

namespace DcsGauges.Input.Processors.Swipe
{
    class IntermediateSwipeProcessor : IInputProcessor
    {
        #region Inner Types        

        public enum SwipeAxis
        {
            Horizontal,
            Vertical,
        }

        public class SwipeEventArgs : EventArgs
        {
            public int          Delta       { get; private set; }
            public SwipeAxis    Axis        { get; private set; }
            public GameTime     GameTime    { get; private set; }

            public SwipeEventArgs(int delta, SwipeAxis axis, GameTime gt)
            {
                this.Delta              = delta;
                this.Axis               = axis;
                this.GameTime           = gt;
            }
        }

        #endregion


        #region Fields & Properties

        private Point?                  swipeStart                      = null;
        private Point?                  lastSwipeEventCoordinate        = null;
        private GuiRenderableBase       renderable                      = null;

        private bool IsSwiping
        {
            get { return this.swipeStart.HasValue; }
        }

        #endregion


        #region Events

        public event EventHandler<SwipeEventArgs>                   SwipeEvent                  = delegate { };

        #endregion


        #region Constructors

        public IntermediateSwipeProcessor(GuiRenderableBase renderable)
        {
            this.renderable                 = renderable;
        }

        #endregion


        #region Interface Implementation

        public void InjectMouseEvent(Events.MouseEvent evt, GameTime gt)
        {
            if (!this.IsSwiping && evt.Button == Events.MouseEvent.MouseButtons.Left && evt.EventType == Events.MouseEvent.EventTypes.MouseDown)
            {
                if (this.renderable.ViewportRect.Contains(evt.ScreenCoordinates))
                {
                    this.EnterSwipingState(evt);
                }
            }
            else if (this.IsSwiping && evt.Button == Events.MouseEvent.MouseButtons.Left)
            {
                this.FireSwipingEvent(evt, gt);
            }
            else
            {
                this.LeaveSwipingState();
            }
        }

        #endregion


        #region Helpers & Internals

        private void EnterSwipingState(Events.MouseEvent evt)
        {
            this.swipeStart                     = evt.ScreenCoordinates;
            this.lastSwipeEventCoordinate       = evt.ScreenCoordinates;
        }

        private void LeaveSwipingState()
        {
            this.swipeStart                     = null;
            this.lastSwipeEventCoordinate       = null;
        }


        private void FireSwipingEvent(Events.MouseEvent evt, GameTime gt)
        {
            int deltaX                          = evt.ScreenCoordinates.X - this.lastSwipeEventCoordinate.Value.X;
            int deltaY                          = evt.ScreenCoordinates.Y - this.lastSwipeEventCoordinate.Value.Y;
            SwipeAxis axis                      = Math.Abs(deltaX) > Math.Abs(deltaY) ? SwipeAxis.Horizontal : SwipeAxis.Vertical;
            int delta                           = axis == SwipeAxis.Horizontal ? deltaX : deltaY;

            SwipeEventArgs args                 = new SwipeEventArgs(delta, axis, gt);
            this.SwipeEvent(this, args);

            this.lastSwipeEventCoordinate       = evt.ScreenCoordinates;
        }

        #endregion

    }
}
